﻿using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CutShuFa
{
    public class CutHelper
    {
        Mat img, img2;
        OpenCvSharp.Point[][] contours;
        List<OpenCvSharp.Point[]> select_contours;


        //img转Image
        public Bitmap GetImage()
        {
            return img2.ToBitmap();
        }


        internal Bitmap Cut()
        {
            if(select_contours == null || select_contours.Count == 0) return null;
            // 遍历select_contours中的轮廓查找矩形框
            OpenCvSharp.Point p1 = new OpenCvSharp.Point(int.MaxValue, int.MaxValue);
            OpenCvSharp.Point p2 = new OpenCvSharp.Point(0, 0);
            foreach (var item in select_contours)
            {
                // 获取轮廓的边界框
                var rect = Cv2.BoundingRect(item);
                if (rect.X < p1.X)
                {
                    p1.X = rect.X;
                }
                if (rect.X + rect.Width > p2.X)
                {
                    p2.X = rect.X + rect.Width;
                }
                if (rect.Y < p1.Y)
                {
                    p1.Y = rect.Y;
                }
                if (rect.Y + rect.Height > p2.Y)
                {
                    p2.Y = rect.Y + rect.Height;
                }
            }
            select_contours = null;
            // 裁剪图片
            return img[p1.Y, p2.Y, p1.X, p2.X].ToBitmap();
        }

        public void SelectByRect(Rectangle r)
        {            
            // 在img中画矩形框
            img2 = img.Clone();
            // 查找在矩形内的轮廓
            select_contours = new List<OpenCvSharp.Point[]>();
            for (int i = 0; i < contours.Length; i++)
            {
                // 获取轮廓的边界框
                var rect = Cv2.BoundingRect(contours[i]);
                // 判断边界框是否在矩形框内
                if (rect.X >= r.X && rect.Y >= r.Y && rect.X + rect.Width <= r.X + r.Width && rect.Y + rect.Height <= r.Y + r.Height)
                {
                    // 绘制轮廓
                    select_contours.Add(contours[i]);
                }
            }
            Cv2.DrawContours(img2, select_contours, -1, new Scalar(0, 0, 255), 2);
        }

        public bool SelectByPoint(OpenCvSharp.Point point)
        {
            OpenCvSharp.Point[] select_contour = null;
            double min_area = double.MaxValue;
            // 判断点在哪个轮廓中
            for (int i = 0; i < contours.Length; i++)
            {
                var c = Cv2.PointPolygonTest(contours[i], point, false);
                if (c >= 0)
                {
                    // 计算轮廓面积
                    double area = Cv2.ContourArea(contours[i]);
                    if (area < min_area)
                    {
                        select_contour = contours[i];
                        min_area = area;
                    }
                }
            }
            if (select_contour == null)
            {
                return false;
            }
            else
            {
                if (select_contours != null)
                {
                    if (select_contours.Contains(select_contour))
                    {
                        select_contours.Remove(select_contour);
                    }
                    else
                    {
                        select_contours.Add(select_contour);
                    }
                }
                else
                {
                    select_contours = new List<OpenCvSharp.Point[]>() { select_contour };
                }
                img2 = img.Clone();
                if(select_contours.Count > 0)
                    Cv2.DrawContours(img2, select_contours, -1, new Scalar(0, 0, 255), 2);
                return true;
            }
        }

        //Opencv 
        public CutHelper(string path)
        {
            //Opencv 打开图片
            img = Cv2.ImRead(path);
            //转为灰度图
            Mat gray = new Mat();
            Cv2.CvtColor(img, gray, ColorConversionCodes.BGR2GRAY);
            //对图片进行二值化
            Mat threshold = new Mat();
            Cv2.Threshold(gray, threshold, 0, 255, ThresholdTypes.Binary | ThresholdTypes.Otsu);
            //OpenCvSharp对mat img反色
            //Cv2.BitwiseNot(threshold, threshold);

            //寻找轮廓
            Cv2.FindContours(threshold, out contours, out HierarchyIndex[] hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);

            //绘制轮廓
            //Cv2.DrawContours(img, contours, -1, new Scalar(0, 0, 255), 2);

            img2 = img.Clone();
        }


    }
}
